package com.hx.jvm.proxy.assit;

import javassist.*;

import java.lang.reflect.Method;

/**
 * @author Minghua Chen
 * @date 2020-08-29 21:45
 */
public class JavassitMain {
    public static void main(String[] args) throws Exception {
        ClassPool classPool = ClassPool.getDefault();
        // 指定要生成分类名
        CtClass ctClass = classPool.makeClass("com.hx.jvm.proxy.assit.JavassitDemo");
        StringBuffer sb = null;
        // 创建字段 并设置修饰符
        CtField field = new CtField(classPool.get("java.lang.String"), "prop", ctClass);
        field.setModifiers(Modifier.PRIVATE);
        // 为字段设置get和set方法
        ctClass.addMethod(CtNewMethod.setter("setProp", field));
        ctClass.addMethod(CtNewMethod.getter("getProp", field));
        // 添加并设置初始值
        ctClass.addField(field, CtField.Initializer.constant("MyName"));
        // 创建构造方法
        CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass);
        // 设置构造方法
        sb = new StringBuffer();
        sb.append("{\n prop = \"MyName\";\n}");
        ctConstructor.setBody(sb.toString());
        ctClass.addConstructor(ctConstructor);
        // 添加一个方法
        CtMethod ctMethod = new CtMethod(CtClass.voidType, "execute", new CtClass[]{}, ctClass);
        ctMethod.setModifiers(Modifier.PUBLIC);
        sb = new StringBuffer();
        sb.append("System.out.println(\"execute():\"+prop);");
        ctMethod.setBody(sb.toString());
        ctClass.addMethod(ctMethod);
        //写入到指定的目录
        ctClass.writeFile("D:\\tmp\\assit");
        Class<?> clazz = ctClass.toClass();
        Object obj = clazz.newInstance();
        Method method = obj.getClass().getMethod("execute");
        method.invoke(obj);
        //System.out.println("execute():"+prop);
    }

    /**  字节码反编译后的代码
     * package com.hx.jvm.proxy.assit;
     *
     * import java.io.PrintStream;
     *
     * public class JavassitDemo
     * {
     *   private String prop = "MyName";
     *
     *   public void setProp(String paramString)
     *   {
     *     this.prop = paramString;
     *   }
     *
     *   public String getProp()
     *   {
     *     return this.prop;
     *   }
     *
     *   public void execute()
     *   {
     *     System.out.println("execute():" + this.prop);
     *   }
     * }
     */

}
